<template>
  <div class="form-builder">
    <!-- 表单标题 -->
    <h2 v-if="formTitle" class="text-xl font-bold text-gray-800 mb-4">
      {{ formTitle }}
    </h2>
    
    <!-- 表单内容 -->
    <form @submit.prevent="handleSubmit" class="space-y-4">
      <!-- 根据字段配置动态生成表单项 -->
      <div v-for="field in fields" :key="field.name" class="form-group">
        <label
          :for="field.name"
          class="block text-sm font-medium text-gray-700 mb-1"
          :class="{ 'text-red-600': field.required }"
        >
          {{ field.label }}
          <span v-if="field.required" class="ml-1">*</span>
        </label>
        
        <!-- 单行文本输入框 -->
        <input
          v-if="field.type === 'text' || field.type === 'number' || field.type === 'email' || field.type === 'password'"
          :id="field.name"
          :type="field.type"
          v-model="formData[field.name]"
          :placeholder="field.placeholder || ''"
          :class="[
            'w-full px-4 py-2 border rounded-lg focus:ring-2 focus:outline-none transition-all',
            errors[field.name] ? 'border-red-500 focus:border-red-500 focus:ring-red-200' : 'border-gray-300 focus:border-indigo-500 focus:ring-indigo-200'
          ]"
          :disabled="field.disabled || false"
          :min="field.min"
          :max="field.max"
          :step="field.step"
        />
        
        <!-- 多行文本输入框 -->
        <textarea
          v-else-if="field.type === 'textarea'"
          :id="field.name"
          v-model="formData[field.name]"
          :placeholder="field.placeholder || ''"
          :rows="field.rows || 4"
          :class="[
            'w-full px-4 py-2 border rounded-lg focus:ring-2 focus:outline-none transition-all',
            errors[field.name] ? 'border-red-500 focus:border-red-500 focus:ring-red-200' : 'border-gray-300 focus:border-indigo-500 focus:ring-indigo-200'
          ]"
          :disabled="field.disabled || false"
        />
        
        <!-- 下拉选择框 -->
        <select
          v-else-if="field.type === 'select'"
          :id="field.name"
          v-model="formData[field.name]"
          :class="[
            'w-full px-4 py-2 border rounded-lg focus:ring-2 focus:outline-none transition-all',
            errors[field.name] ? 'border-red-500 focus:border-red-500 focus:ring-red-200' : 'border-gray-300 focus:border-indigo-500 focus:ring-indigo-200'
          ]"
          :disabled="field.disabled || false"
        >
          <option v-if="!field.required" value="">请选择...</option>
          <option v-for="option in field.options" :key="option.value" :value="option.value">
            {{ option.label }}
          </option>
        </select>
        
        <!-- 单选框组 -->
        <div v-else-if="field.type === 'radio'" class="space-y-2">
          <label
            v-for="option in field.options"
            :key="option.value"
            class="inline-flex items-center space-x-2 cursor-pointer"
          >
            <input
              type="radio"
              :name="field.name"
              :value="option.value"
              v-model="formData[field.name]"
              :class="'text-indigo-600 focus:ring-indigo-500'"
              :disabled="field.disabled || false"
            />
            <span>{{ option.label }}</span>
          </label>
        </div>
        
        <!-- 复选框组 -->
        <div v-else-if="field.type === 'checkbox'" class="space-y-2">
          <label
            v-for="option in field.options"
            :key="option.value"
            class="inline-flex items-center space-x-2 cursor-pointer"
          >
            <input
              type="checkbox"
              :name="`${field.name}_${option.value}`"
              :value="option.value"
              :checked="formData[field.name]?.includes(option.value)"
              @change="handleCheckboxChange(field.name, option.value)"
              :class="'text-indigo-600 focus:ring-indigo-500'"
              :disabled="field.disabled || false"
            />
            <span>{{ option.label }}</span>
          </label>
        </div>
        
        <!-- 日期选择器 -->
        <input
          v-else-if="field.type === 'date' || field.type === 'datetime-local'"
          :id="field.name"
          :type="field.type"
          v-model="formData[field.name]"
          :class="[
            'w-full px-4 py-2 border rounded-lg focus:ring-2 focus:outline-none transition-all',
            errors[field.name] ? 'border-red-500 focus:border-red-500 focus:ring-red-200' : 'border-gray-300 focus:border-indigo-500 focus:ring-indigo-200'
          ]"
          :disabled="field.disabled || false"
        />
        
        <!-- 错误信息 -->
        <p v-if="errors[field.name]" class="mt-1 text-sm text-red-600">
          {{ errors[field.name] }}
        </p>
        
        <!-- 帮助文本 -->
        <p v-if="field.helpText && !errors[field.name]" class="mt-1 text-sm text-gray-500">
          {{ field.helpText }}
        </p>
      </div>
      
      <!-- 操作按钮 -->
      <div class="flex justify-end gap-3 pt-4 border-t border-gray-200">
        <button
          type="button"
          @click="handleCancel"
          :disabled="loading"
          class="px-4 py-2 border border-gray-300 rounded-lg text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors"
        >
          取消
        </button>
        <button
          type="submit"
          :disabled="loading"
          class="px-4 py-2 bg-indigo-600 border border-transparent rounded-lg text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors"
        >
          <i v-if="loading" class="fa fa-spinner fa-spin mr-1"></i>
          {{ submitText || '提交' }}
        </button>
      </div>
    </form>
  </div>
</template>

<script setup>
import { ref, reactive, watch, computed } from 'vue';
import { useValidator } from '@/composables/useValidator';

// 定义组件属性
const props = defineProps({
  // 表单标题
  formTitle: {
    type: String,
    default: ''
  },
  
  // 表单字段配置
  fields: {
    type: Array,
    default: () => []
  },
  
  // 初始数据
  initialData: {
    type: Object,
    default: () => ({})
  },
  
  // 提交按钮文本
  submitText: {
    type: String,
    default: '提交'
  },
  
  // 加载状态
  loading: {
    type: Boolean,
    default: false
  }
});

// 定义事件
const emit = defineEmits(['submit', 'cancel']);

// 使用验证器
const { validateField, validateForm, errors: validationErrors } = useValidator();

// 表单数据
const formData = reactive({});

// 错误信息
const errors = ref({});

// 初始化表单数据
const initializeFormData = () => {
  // 清空表单数据
  Object.keys(formData).forEach(key => {
    delete formData[key];
  });
  
  // 设置初始值
  props.fields.forEach(field => {
    // 如果有初始数据，则使用初始数据
    if (props.initialData.hasOwnProperty(field.name)) {
      // 对于复选框组，确保是数组
      if (field.type === 'checkbox' && !Array.isArray(props.initialData[field.name])) {
        formData[field.name] = [];
      } else {
        formData[field.name] = props.initialData[field.name];
      }
    }
    // 如果没有初始数据但有默认值，则使用默认值
    else if (field.hasOwnProperty('default')) {
      formData[field.name] = field.default;
    }
    // 对于复选框组，默认为空数组
    else if (field.type === 'checkbox') {
      formData[field.name] = [];
    }
    // 其他字段默认为空字符串
    else {
      formData[field.name] = '';
    }
  });
  
  // 清空错误信息
  errors.value = {};
};

// 当初始数据或字段配置变化时，重新初始化表单
watch([() => props.initialData, () => props.fields], () => {
  initializeFormData();
}, { deep: true, immediate: true });

// 处理复选框变化
const handleCheckboxChange = (fieldName, value) => {
  // 确保是数组
  if (!Array.isArray(formData[fieldName])) {
    formData[fieldName] = [];
  }
  
  // 查找值在数组中的索引
  const index = formData[fieldName].indexOf(value);
  
  // 如果值已存在，则移除；否则，添加
  if (index > -1) {
    formData[fieldName].splice(index, 1);
  } else {
    formData[fieldName].push(value);
  }
};

// 表单验证
const validateFormData = () => {
  let isValid = true;
  const newErrors = {};
  
  // 验证每个字段
  props.fields.forEach(field => {
    // 如果字段有验证规则，则进行验证
    if (field.rules && field.rules.length > 0) {
      const error = validateField(field.name, formData[field.name], field.rules);
      if (error) {
        newErrors[field.name] = error;
        isValid = false;
      }
    }
    // 如果字段为必填且值为空，则添加错误信息
    else if (field.required && (!formData[field.name] || (Array.isArray(formData[field.name]) && formData[field.name].length === 0))) {
      newErrors[field.name] = `${field.label}为必填项`;
      isValid = false;
    }
  });
  
  // 更新错误信息
  errors.value = newErrors;
  
  return isValid;
};

// 处理表单提交
const handleSubmit = () => {
  // 验证表单
  if (!validateFormData()) {
    return;
  }
  
  // 深度克隆表单数据，避免直接修改源数据
  const formDataCopy = JSON.parse(JSON.stringify(formData));
  
  // 触发提交事件
  emit('submit', formDataCopy);
};

// 处理取消
const handleCancel = () => {
  emit('cancel');
};
</script>

<style scoped>
.form-builder {
  font-family: inherit;
}

.form-group {
  margin-bottom: 1rem;
}

input[type="checkbox"]:focus,
input[type="radio"]:focus {
  outline: none;
}

/* 表单动画效果 */
input,
textarea,
select {
  transition: all 0.2s ease-in-out;
}

input:focus,
textarea:focus,
select:focus {
  transform: translateY(-1px);
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}

/* 错误状态动画 */
input.border-red-500,
textarea.border-red-500,
select.border-red-500 {
  animation: shake 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

@keyframes shake {
  10%, 90% {
    transform: translateX(-1px);
  }
  20%, 80% {
    transform: translateX(2px);
  }
  30%, 50%, 70% {
    transform: translateX(-3px);
  }
  40%, 60% {
    transform: translateX(3px);
  }
}
</style>